import os.path
import sys
import time

from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QLineEdit, QMessageBox, \
    QTableWidget, QTableWidgetItem, QApplication, QAbstractItemView
from PySide6.QtGui import Qt
from easy_tools.utils.file import get_user_read_size, get_dir_or_file_size
from PySide6.QtCore import QThread, Signal, QObject


class WorkerThread(QObject):
    scan = Signal(int)

    def __init__(self):
        super().__init__()

    def scan_proc(self):
        self.scan.emit(1)


class SystemStorageScanWidget(QWidget):
    """
    todo 多线程未生效
    """
    def __init__(self):
        super().__init__()
        self.table = None
        self._init()

    def _init(self):
        self.thread = QThread(self)
        self.worker = WorkerThread()
        self.worker.moveToThread(self.thread)

        self.vbox = QVBoxLayout()
        self.vbox.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.setLayout(self.vbox)
        self.input_path_widget = QLineEdit('', self)
        self.confirm = QPushButton('扫描', self)

        input_layout = QHBoxLayout()
        input_layout.addWidget(QLabel('扫描的目录/文件: ', self), 1)
        input_layout.addWidget(self.input_path_widget, 3)

        self.vbox.addLayout(input_layout)
        self.vbox.addWidget(self.confirm)

        self.worker.scan.connect(self._scan)
        self.confirm.clicked.connect(self.worker.scan_proc)
        self.thread.start()

    def _scan(self):
        if not self.input_path_widget.text():
            QMessageBox.question(self, '错误', '扫描地址不能为空', QMessageBox.StandardButton.Ok)
            return
        dir_or_file_path = self.input_path_widget.text()
        if not os.path.exists(dir_or_file_path):
            QMessageBox.question(self, '错误', '该目录/文件地址不存在, 请检查后重新尝试', QMessageBox.StandardButton.Ok)
            return
        dir_or_file_path = dir_or_file_path.replace('\\', '/')

        if self.table:
            self.vbox.removeWidget(self.table)
            self.table.close()

        if os.path.isfile(dir_or_file_path):
            file_name = dir_or_file_path[-dir_or_file_path[::-1].index('/'):]
            self.table = self._get_table(1, 3)
            self.table.setItem(0, 0, QTableWidgetItem(file_name))
            self.table.setItem(0, 1, QTableWidgetItem(get_user_read_size(os.path.getsize(dir_or_file_path), 2)))
            self.table.setItem(0, 2, QTableWidgetItem(dir_or_file_path))
        elif os.path.isdir(dir_or_file_path):
            self._scan_dir(dir_or_file_path)

    def _scan_dir(self, dir_path):
        dir_and_files = os.listdir(dir_path)
        self.table = self._get_table(len(dir_and_files), 3)

        infos = []
        for i in range(len(dir_and_files)):
            sub_ = dir_and_files[i]
            sub_path = os.path.join(dir_path, sub_)
            size = get_dir_or_file_size(sub_path)
            if os.path.isdir(sub_path):
                sub_ += '/'
            infos.append([sub_, size, sub_path])

        infos.sort(key=lambda x: x[1], reverse=True)

        for i in range(len(dir_and_files)):
            for j in range(len(infos[i])):
                if j == 1:
                    infos[i][j] = get_user_read_size(infos[i][j], 2)
                self.table.setItem(i, j, QTableWidgetItem(infos[i][j]))

        if self.table:
            self.vbox.addWidget(self.table)

        QMessageBox.question(self, '提示', '扫描完成', QMessageBox.StandardButton.Ok)

    def _get_table(self, line, column):
        table = QTableWidget(line, column, self)
        table.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
        table.setHorizontalHeaderLabels(['文件名', '大小', '文件路径'])
        return table

    def close(self) -> bool:
        if self.table:
            self.table.close()
        if self.thread:
            self.thread.quit()
        return super().close()


if __name__ == '__main__':
    app = QApplication()
    win = SystemStorageScanWidget()
    win.show()
    sys.exit(app.exec())
